package AS;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Date;

import javax.crypto.Cipher;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import tickets.CipherTicket;
import tickets.Ticket;
import userdb.UserDb;

public class ASThread extends Thread {

  private Socket socket = null;
  private AS as;

  public ASThread(Socket socket, AS server) {
    super();
    this.socket = socket;
    this.as = server;
  }

  
  @Override
  public void run() {
    try {
      System.out.println("AS: Connection established..");
      ObjectInputStream oib = new ObjectInputStream(socket.getInputStream());

      String name = (String) oib.readObject().toString();
      System.out.println("AS: Client " + socket.getInetAddress() + ":" + socket.getPort() + " sent me the name: " + name);
      SealedObject so = getSealedObject(name);

      ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
      if (so != null) {
        oos.writeObject("OK");
        oos.writeObject(so);
        System.out.println("SealedObject sent");
      } else {
        oos.writeObject("NOK");
      }
      oos.flush();

      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      socket.close();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      System.out.println("AS: ...");
      e.printStackTrace();
    }
  }

  private SealedObject getSealedObject(String name) {
    SealedObject tgTicket = null;
    System.out.println("Password fuer den Benutzer " + name + " wird ermittelt.");
    byte[] passwort = UserDb.SINGLETON.getUsers().get(name);
    try {
      // wenn user Vorhanden
      if (passwort != null) {
        System.out.println("Password fuer den Benutzer " + name + " wurde gefunden: " + passwort);

        SecretKey kaas = new SecretKeySpec(passwort, "AES");
        System.out.println("passwort: UID" + SecretKey.serialVersionUID + " " + kaas.getEncoded());

        // zuf�lliger Schl�ssel
        SecretKey katgs = as.getKeygen().generateKey();
        Cipher c = Cipher.getInstance(as.getKastgs().getAlgorithm());
        c.init(Cipher.ENCRYPT_MODE, as.getKastgs());

        // Kas,tgs(A,Ka,tgs)
        tgTicket = new SealedObject(new Ticket(name, katgs, new Date()), c);

        Cipher cc = Cipher.getInstance(kaas.getAlgorithm());
        cc.init(Cipher.ENCRYPT_MODE, kaas);

        // Ka,as(Ka,tgs,tgTicket);
        tgTicket = new SealedObject(new CipherTicket(tgTicket, katgs), cc);

      } else {
        System.out.println("Benutzer " + name + " wurde in der Datenbank nicht gefunden");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    return tgTicket;
  }

}
